package response

import (
	"net/http"

	jsoniter "github.com/json-iterator/go"

	"github.com/gin-gonic/gin"
)

type Json struct {
	Errcode int    `json:"errcode"`
	Msg     string `json:"msg"`
	Data    any    `json:"data"`
}

// Response 响应json数据
func (j *Json) Response(ctx *gin.Context) {
	if j.Msg == "" {
		// 获取错误码对应消息
		if errcodeMsg, exists := Errcodes[j.Errcode]; exists {
			j.Msg = errcodeMsg
		}
	}
	// ctx.JSON(http.StatusOK, j)

	json := jsoniter.ConfigCompatibleWithStandardLibrary
	jsonData, err := json.Marshal(j)
	if err != nil {
		failJson := NewFailJson("响应异常！json序列化数据失败：" + err.Error())
		ctx.JSON(http.StatusOK, failJson)
		return
	}
	ctx.Data(http.StatusOK, "application/json; charset=utf-8", jsonData)
}

// AbortResponse 响应json数据并终止当前请求执行
func (j *Json) AbortResponse(ctx *gin.Context) {
	j.Response(ctx)
	ctx.Abort()
}

// SuccessJson 成功的json
type SuccessJson struct {
	Json
}

// NewSuccessJson 成功json构造函数
func NewSuccessJson(data any, msg ...string) *SuccessJson {
	message := ""
	if len(msg) > 0 {
		message = msg[0]
	}
	sj := &SuccessJson{}
	sj.Errcode = 0
	sj.Msg = message
	sj.Data = data
	return sj
}

// Success 响应成功的json数据
func Success(ctx *gin.Context, data any, msg ...string) {
	NewSuccessJson(data, msg...).Response(ctx)
}

// SuccessEmptyJson 成功的空json数据
func SuccessEmptyJson() *SuccessJson {
	return NewSuccessJson(nil)
}

// FailJson 失败的json
type FailJson struct {
	Json
}

// NewFailJson 成功json构造函数
func NewFailJson(msg string, errcode ...int) *FailJson {
	errcodeVal := 500
	if len(errcode) > 0 {
		errcodeVal = errcode[0]
	}
	fj := &FailJson{}
	fj.Errcode = errcodeVal
	fj.Msg = msg
	return fj
}

// Fail 响应失败的json数据
func Fail(ctx *gin.Context, msg string, errcode ...int) {
	NewFailJson(msg, errcode...).Response(ctx)
}

// FailErrcodeJson 失败错误码的json数据
func FailErrcodeJson(errcode int) *FailJson {
	return NewFailJson("", errcode)
}

// FailErrcode 响应失败错误码的json数据
func FailErrcode(ctx *gin.Context, errcode int) {
	FailErrcodeJson(errcode).Response(ctx)
}

// AbortSuccess 响应成功的json数据并终止当前请求执行
func AbortSuccess(ctx *gin.Context, data any, msg ...string) {
	NewSuccessJson(data, msg...).AbortResponse(ctx)
}

// AbortFail 响应失败的json数据并终止当前请求执行
func AbortFail(ctx *gin.Context, msg string, errcode ...int) {
	NewFailJson(msg, errcode...).AbortResponse(ctx)
}
